package com.qf.common.base.hanlder;

import com.qf.common.base.exception.ControllerException;
import com.qf.common.base.exception.DaoException;
import com.qf.common.base.exception.ServiceException;
import com.qf.common.base.result.ResponseResult;
import com.qf.common.base.result.ResultCode;
import com.qf.common.base.vo.ErrorData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@RestControllerAdvice
@Slf4j
public class GlobalHandlerException {

    @ExceptionHandler(Exception.class)
    public ResponseResult<Object> handlerException(Exception ex) {
        log.error(ex.getMessage());
        return ResponseResult.error();
    }

    @ExceptionHandler(DaoException.class)
    public ResponseResult<Object> handlerException(DaoException ex) {
        return ResponseResult.error(ex.getResultCode());
    }

    @ExceptionHandler(ServiceException.class)
    public ResponseResult<Object> handlerException(ServiceException ex) {
        return ResponseResult.error(ex.getResultCode());
    }

    @ExceptionHandler(ControllerException.class)
    public ResponseResult<Object> handlerException(ControllerException ex) {
        return ResponseResult.error(ex.getResultCode());
    }

    /**
     * 单参数校验的时候抛出异常
     * errors
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseResult<List<String>> handlerConstraintViolationException(ConstraintViolationException ex) {
        // 针对普通校验 简单的错误信息
        List<String> errors = new ArrayList<>();
        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
        constraintViolations.forEach(constraintViolation -> {
            // 获取注解上msg属性的值
            errors.add(constraintViolation.getMessage());
        });
        return ResponseResult.error(ResultCode.PARAMS_IS_INVALID, errors);
    }

    @ExceptionHandler(BindException.class)
    public ResponseResult<List<ErrorData>> handlerBindException(BindException ex) {
        List<ObjectError> allErrors = ex.getAllErrors();
        List<ErrorData> errors = new ArrayList<>();
        allErrors.forEach(error -> {
            errors.add(new ErrorData(error.getObjectName(), error.getDefaultMessage()));
        });
//        List<String> list = ex.getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.toList());
        return ResponseResult.success(ResultCode.PARAMS_IS_INVALID, errors);
    }


}
